ESP32/8266 蓝牙配网 Blufi 开源

您所在的位置:网站首页 arduino esp8266 wifi ESP32/8266 蓝牙配网 Blufi 开源

ESP32/8266 蓝牙配网 Blufi 开源

2023-07-19 07:29| 来源: 网络整理| 查看: 265

概览

BluFi 是一款基于蓝牙通道的 Wi-Fi 网络配置功能,适用于 ESP32。它通过安全协议将 Wi-Fi 配置和证书传输到 ESP32,然后 ESP32 可基于这些信息连接到 AP 或建立 SoftAP。

用户可按需自定义用于对称加密、非对称加密和校验的算法。这里我们采用 DH 算法进行密钥协商、128-AES 算法用于数据加密、CRC16 算法用于校验和验证。

BluFi 流程

BluFi 配网功能包含配置 SoftAP 和 Station 两部分。

下面以配置 Station 为例说明配置步骤。 BluFi 配网的配置 Station 包含广播、连接、服务发现、协商共享密钥、传输数据、回传连接状态等步骤。

代码

引入相关库文件

#include #include #include "BluetoothSerial.h"

定义变量

String ssids_array[50]; String network_string; String connected_string; const char* pref_ssid = ""; const char* pref_pass = ""; String client_wifi_ssid; String client_wifi_password; const char* bluetooth_name = "ESP32 BLE"; long start_wifi_millis; long wifi_timeout = 10000; bool bluetooth_disconnect = false; enum wifi_setup_stages { NONE, SCAN_START, SCAN_COMPLETE, SSID_ENTERED, WAIT_PASS, PASS_ENTERED, WAIT_CONNECT, LOGIN_FAILED }; enum wifi_setup_stages wifi_stage = NONE; BluetoothSerial SerialBT; Preferences preferences;

WIFI联网函数

bool init_wifi() { String temp_pref_ssid = preferences.getString("pref_ssid"); String temp_pref_pass = preferences.getString("pref_pass"); pref_ssid = temp_pref_ssid.c_str(); pref_pass = temp_pref_pass.c_str(); Serial.println(pref_ssid); Serial.println(pref_pass); WiFi.config(INADDR_NONE, INADDR_NONE, INADDR_NONE); WiFi.mode(WIFI_STA); Serial.println(); Serial.print("Connecting to "); Serial.println(pref_ssid); WiFi.begin(pref_ssid, pref_pass); while (WiFi.status() != WL_CONNECTED) { delay(500); Serial.print("."); if (millis() - start_wifi_millis > wifi_timeout) { WiFi.disconnect(true, true); return false; } } Serial.println(); Serial.print("ESP32-CAM IP Address: "); Serial.println(WiFi.localIP()); return true; }

扫码周围已存在网络

void scan_wifi_networks() { WiFi.mode(WIFI_STA); // WiFi.scanNetworks will return the number of networks found int n = WiFi.scanNetworks(); if (n == 0) { SerialBT.println("no networks found"); } else { SerialBT.println(); SerialBT.print(n); SerialBT.println(" networks found"); delay(1000); for (int i = 0; i < n; ++i) { ssids_array[i + 1] = WiFi.SSID(i); Serial.print(i + 1); Serial.print(": "); Serial.println(ssids_array[i + 1]); network_string = i + 1; network_string = network_string + ": " + WiFi.SSID(i) + " (Strength:" + WiFi.RSSI(i) + ")"; SerialBT.println(network_string); } wifi_stage = SCAN_COMPLETE; } }

回调函数,从蓝牙获取wifi登陆信息

void callback(esp_spp_cb_event_t event, esp_spp_cb_param_t *param) { if (event == ESP_SPP_SRV_OPEN_EVT) { wifi_stage = SCAN_START; } if (event == ESP_SPP_DATA_IND_EVT && wifi_stage == SCAN_COMPLETE) { // data from phone is SSID int client_wifi_ssid_id = SerialBT.readString().toInt(); client_wifi_ssid = ssids_array[client_wifi_ssid_id]; wifi_stage = SSID_ENTERED; } if (event == ESP_SPP_DATA_IND_EVT && wifi_stage == WAIT_PASS) { // data from phone is password client_wifi_password = SerialBT.readString(); client_wifi_password.trim(); wifi_stage = PASS_ENTERED; } }

回调显示已分配IP地址

void callback_show_ip(esp_spp_cb_event_t event, esp_spp_cb_param_t *param) { if (event == ESP_SPP_SRV_OPEN_EVT) { SerialBT.print("ESP32 IP: "); SerialBT.println(WiFi.localIP()); bluetooth_disconnect = true; } }

联网完成,断开蓝牙

void disconnect_bluetooth() { delay(1000); Serial.println("BT stopping"); SerialBT.println("Bluetooth disconnecting..."); delay(1000); SerialBT.flush(); SerialBT.disconnect(); SerialBT.end(); Serial.println("BT stopped"); delay(1000); bluetooth_disconnect = false; }

启动程序

void setup() { /********************** BluetoothWifi ***************************/ Serial.begin(115200); Serial.println("Booting..."); preferences.begin("wifi_access", false); if (!init_wifi()) { // Connect to Wi-Fi fails SerialBT.register_callback(callback); } else { SerialBT.register_callback(callback_show_ip); } SerialBT.begin(bluetooth_name); /********************** 放置你的setup代码,执行一次 ***************************/ Serial.println("Test just once..."); }

循环检测是否需要配网

void loop() { /********************** BluetoothWifi ***************************/ if (bluetooth_disconnect) { disconnect_bluetooth(); } switch (wifi__stage) { case SCAN_START: SerialBT.println("Scanning Wi-Fi networks"); Serial.println("Scanning Wi-Fi networks"); scan_wifi_networks(); SerialBT.println("Please enter the number for your Wi-Fi"); wifi_stage = SCAN_COMPLETE; break; case SSID_ENTERED: SerialBT.println("Please enter your Wi-Fi password"); Serial.println("Please enter your Wi-Fi password"); wifi_stage = WAIT_PASS; break; case PASS_ENTERED: SerialBT.println("Please wait for Wi-Fi connection..."); Serial.println("Please wait for Wi_Fi connection..."); wifi_stage = WAIT_CONNECT; preferences.putString("pref_ssid", client_wifi_ssid); preferences.putString("pref_pass", client_wifi_password); if (init_wifi()) { // Connected to WiFi connected_string = "ESP32 IP: "; connected_string = connected_string + WiFi.localIP().toString(); SerialBT.println(connected_string); Serial.println(connected_string); bluetooth_disconnect = true; } else { // try again wifi_stage = LOGIN_FAILED; } break; case LOGIN_FAILED: SerialBT.println("Wi-Fi connection failed"); Serial.println("Wi-Fi connection failed"); delay(2000); wifi_stage = SCAN_START; break; } /********************** 放置你的loop代码,重复执行 ***************************/ Serial.println("Test repeat..."); delay(5000); }

编译好的二进制文件,直接烧录,即可体验。https://download.csdn.net/download/u014331212/85019734



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3